using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Barrage.Global;
using System.IO;
using SlimDX;

namespace Spacedash.Logic
{
    /// <summary>
    /// Ship model holds information about which mesh will be used to render a player's ship, and where will be placed its thrusters.
    /// </summary>
    public class ShipModel
    {
        static bool pathAdded = false;
        static void AddPath()
        {
            if (!Store.PathConfig.Contains(SHIP_PATH))
            {
                Store.PathConfig.Add(SHIP_PATH, SHIP_DEFAULT_PATH);
                pathAdded = true;
            }
        }

        /// <summary>
        /// Ship path identifier
        /// </summary>
        public const string SHIP_PATH = "ShipPath";
        private const string SHIP_DEFAULT_PATH = "Ships/";
        private const string XML_SHIP_ROOT = "Ship";
        private const string XML_MODEL_ATTRIBUTE = "model";
        private const string XML_SHADOW_ATTRIBUTE = "shadowTexture";
        private const string XML_THRUSTER_OFFSETX_ATTRIBUTE = "thrusterOffsetX";
        private const string XML_THRUSTER_OFFSETY_ATTRIBUTE = "thrusterOffsetY";
        private const string XML_THRUSTER_OFFSETZ_ATTRIBUTE = "thrusterOffsetZ";
        /// <summary>
        /// Loads the specified ship model
        /// </summary>
        /// <param name="name">Ship model name</param>
        /// <returns>Loaded ShipModel instance</returns>
        public static ShipModel Load(string name)
        {
            if (!pathAdded) AddPath();

            XmlDocument xd = new XmlDocument();
            xd.Load(Store.PathConfig[SHIP_PATH] + name + ".xml");
            foreach (XmlNode xn in xd.ChildNodes)
            {
                if (xn.Name.Equals(XML_SHIP_ROOT))
                {
                    return new ShipModel(XmlHelper.GetXMLAttribute(xn, XML_MODEL_ATTRIBUTE), XmlHelper.GetXMLAttribute(xn,XML_SHADOW_ATTRIBUTE), XmlHelper.ParseXMLVector3Attribute(xn, XML_THRUSTER_OFFSETX_ATTRIBUTE,XML_THRUSTER_OFFSETY_ATTRIBUTE,XML_THRUSTER_OFFSETZ_ATTRIBUTE));
                }
            }
            return null;
        }

        /// <summary>
        /// Returns a list with all the available ship models in the ship model directory
        /// </summary>
        /// <returns>List of ship model names</returns>
        public static List<string> GetAvailableModels()
        {
            if (!pathAdded) AddPath();

            List<string> names = new List<string>();
            DirectoryInfo di = new DirectoryInfo(Store.PathConfig[SHIP_PATH]);
            if (!di.Exists) return names;
            FileInfo[] files = di.GetFiles("*.xml", SearchOption.TopDirectoryOnly);
            foreach (FileInfo fi in files)
            {
                string name = fi.Name;
                name = name.Substring(0, name.Length - 4);
                names.Add(name);
            }
            return names;
        }

        string model;
        string shadowTexture;
        Vector3 thrusterOffset;
        /// <summary>
        /// Ship mesh name associated to this model
        /// </summary>
        public string Model { get { return model; } }
        /// <summary>
        /// Shadow texture of this ship
        /// </summary>
        public string ShadowTexture { get { return shadowTexture; } }
        /// <summary>
        /// Offset of the ship's thrusters
        /// </summary>
        public Vector3 ThrusterOffset { get { return thrusterOffset; } }

        /// <summary>
        /// Constructor. Inits values
        /// </summary>
        /// <param name="model">Ship mesh</param>
        /// <param name="shadowTexture">Shadow texture</param>
        /// <param name="thrusterOffset">Thruster Offset</param>
        public ShipModel(string model, string shadowTexture, Vector3 thrusterOffset)
        {
            this.model = model;
            this.shadowTexture = shadowTexture;
            this.thrusterOffset = thrusterOffset;
        }

    }
}
